/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.support.transform.handler;

import cn.easyplatform.EasyPlatformWithLabelKeyException;
import cn.easyplatform.ScriptEvalException;
import cn.easyplatform.ScriptEvalExitException;
import cn.easyplatform.ScriptRuntimeException;
import cn.easyplatform.contexts.ListContext;
import cn.easyplatform.contexts.RecordContext;
import cn.easyplatform.dos.FieldDo;
import cn.easyplatform.dos.Record;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.entities.helper.EventLogic;
import cn.easyplatform.interceptor.CommandContext;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.support.scripting.CompliableScriptEngine;
import cn.easyplatform.support.scripting.ScriptEngineFactory;
import cn.easyplatform.support.transform.Parameter;
import cn.easyplatform.support.transform.TransformerHandler;
import cn.easyplatform.type.FieldType;
import cn.easyplatform.util.RuntimeUtils;

import java.util.List;
import java.util.Map;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class Flating4ListHandler implements
        TransformerHandler<Map<String, List<List<FieldDo>>>> {

    private CommandContext cc;

    private RecordContext rc;

    private CompliableScriptEngine compiler1;

    private CompliableScriptEngine compiler2;

    private ListContext lc;

    private EventLogic el;

    private int firstRowNum, firstColNum, lastRowNum, lastColNum;

    public Flating4ListHandler(CommandContext cc, RecordContext rc,
                               ListContext lc, String logic, int firstRowNum, int firstColNum,
                               int lastRowNum, int lastColNum) {
        this.cc = cc;
        this.rc = rc;
        this.lc = lc;
        this.firstRowNum = firstRowNum;
        this.firstColNum = firstColNum;
        this.lastRowNum = lastRowNum;
        this.lastColNum = lastColNum;
        if (!Strings.isBlank(lc.getBeforeLogic())) {
            EventLogic el = RuntimeUtils.castTo(cc, rc, lc.getBeforeLogic());
            compiler1 = ScriptEngineFactory.createCompilableEngine(cc,
                    el.getContent());
        }
        if (!Strings.isBlank(logic)) {
            el = RuntimeUtils.castTo(cc, rc, logic);
            compiler2 = ScriptEngineFactory.createCompilableEngine(cc,
                    el.getContent());
        }
    }

    @Override
    public void transform(Map<String, List<List<FieldDo>>> data, Parameter parameter) {
        try {
            TableBean tb = cc.getEntity(lc.getBean().getTable());
            for (Map.Entry<String, List<List<FieldDo>>> entry : data.entrySet()) {
                List<List<FieldDo>> records = entry.getValue();
                int rowNums = records.size();
                if (lastRowNum > 0 && rowNums > lastRowNum)
                    rowNums = lastRowNum;
                if (firstRowNum > 0)
                    firstRowNum--;
                int rowIndex = 1;
                for (int row = firstRowNum; row < rowNums; row++) {
                    lc.setParameter("857", rowIndex);
                    Record record = RuntimeUtils.createRecord(cc, tb,
                            tb.isAutoKey());
                    rowIndex++;
                    RecordContext target = lc.createRecord(record);
                    List<FieldDo> objs = records.get(row);
                    RecordContext source = rc.clone();
                    source.setVariable(new FieldDo("SHEET_NAME",
                            FieldType.VARCHAR, entry.getKey()));
                    source.setData(new Record());
                    source.setParameter("759", "IMPORT");
                    int colNums = objs.size();
                    if (lastColNum > 0 && colNums > lastColNum)
                        colNums = lastColNum;
                    if (firstColNum > 0)
                        firstColNum--;
                    for (int col = firstColNum; col < colNums; col++)
                        source.getData().set(objs.get(col));
                    if (compiler1 != null)
                        compiler1.eval(rc, target);
                    if (compiler2 != null) {
                        try {
                            compiler2.eval(source, target);
                        } catch (ScriptEvalExitException ex) {
                            if (!target.getParameterAsBoolean("855"))// 如果855不为真，则直接退出
                                throw new ScriptRuntimeException(
                                        ex.getMessage(),
                                        cc.getMessage(ex.getMessage(),
                                                ex.getRecord()));
                            continue;
                        } catch (ScriptEvalException ex) {
                            ex.setSource(row + ":" + el.toString());
                            throw ex;
                        } catch (EasyPlatformWithLabelKeyException ex) {
                            ex.setSource(row + ":" + el.toString());
                            throw ex;
                        }
                    }
                    lc.appendRecord(target, false);
                }
            }
        } finally {
            if (compiler1 != null)
                compiler1.destroy();
            if (compiler2 != null)
                compiler2.destroy();
        }
    }
}
